package br.com.caelum.dao;

import java.math.BigDecimal;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import br.com.caelum.model.Aluno;
import br.com.caelum.model.Matricula;
import br.com.caelum.vraptor.ioc.Component;

@Component
public class AlunoDAO {
	final private static int CRE_per = 0;
	final private static int CRE_glo = 1;
	
	private Session session;
	
	public AlunoDAO(Session session) {
		this.session = session;
	}
	
	public void salva(Aluno aluno)
	{
		Transaction tx = session.beginTransaction();
		session.save(aluno);
		tx.commit();
	}
	
	public void apaga(Aluno aluno) {
		Transaction tx = session.beginTransaction();
		session.delete(aluno);
		tx.commit();
	}
	
	public void atualiza(Aluno aluno) {
		Transaction tx = session.beginTransaction();
		session.update(aluno);
		tx.commit();
	}
	
	public Aluno carrega(Long id) {
		return (Aluno) this.session.load(Aluno.class, id);
	}
	
	public List<Aluno> listaTudo() {
		List<Aluno> alunos = this.session.createCriteria(Aluno.class).list();
		
		for (Aluno alun : alunos) { 
			/*pega lista de matriculas do aluno*/
			List<Matricula> matriculas = this.session.createCriteria(Matricula.class)
					.add(Restrictions.eq("aluno.aluno_id", alun.getAluno_id()))
					.list();
			
			/*calcula o CRE periodo*/
			BigDecimal[] CREs = new BigDecimal[2];
			CREs = calculaCRE(matriculas);
			alun.setCRE_periodo(CREs[CRE_per]);
			alun.setCRE_geral(CREs[CRE_glo]);
		}
		
		return alunos;
	}
	
	public BigDecimal[] calculaCRE(List<Matricula> matriculas) {
		double CRE_periodo = 0;
		double CRE_geral = 0;
		double numerador_atual = 0;
		double denominador_atual = 0;
		double numerador_geral= 0;
		double denominador_geral = 0;
		BigDecimal[] resultado = new BigDecimal[2];
		
		/*percorre a lista de matriculas*/
		for (Matricula matr : matriculas) {   
			/*calcula o CRE do periodo*/
			if(matr.getAluno().getPeriodo() == matr.getPeriodo()) {
				numerador_atual += ( (matr.getMedia().doubleValue()) * matr.getTurma().getCh() );
				denominador_atual += matr.getTurma().getCh();
			}
			/*calcula o CRE geral*/
			numerador_geral += ( (matr.getMedia().doubleValue()) * matr.getTurma().getCh() );
			denominador_geral += matr.getTurma().getCh();
		}
		CRE_periodo = (numerador_atual == 0) ? (0) : (numerador_atual / denominador_atual);
		CRE_geral = (numerador_geral == 0) ? (0) : (numerador_geral / denominador_geral);
		resultado[CRE_per] = new BigDecimal(CRE_periodo);
		resultado[CRE_glo] = new BigDecimal(CRE_geral);
		
		return resultado;
	}
	
}

